package 模拟真题;

/**
 * @author ShadowLim
 * @create 2022-03-24-18:55
 */
public class 超大玉螺旋丸 {

    /**
     * 核心代码：(K神) https://leetcode-cn.com/problems/spiral-matrix-ii/solution/spiral-matrix-ii-mo-ni-fa-she-ding-bian-jie-qing-x/
     * @param args
     */
    public static void main(String[] args) {
        int[][] ans;
        ans = generateMatrix(30);
        System.out.println(ans[19][19]);    // 819
    }

    private static int[][] generateMatrix(int n) {
        int l = 0, r = n - 1, top = 0, bottom = n - 1;
        int[][] mat = new int[n][n];
        int num = 1, target = n * n;
        while (num <= target) {
            // l --> r
            for (int i = l; i <= r; i++) {
                mat[top][i] = num++;
            }
            top++;
            // top --> bottom
            for (int i = top; i <= bottom; i++) {
                mat[i][r] = num++;
            }
            r--;
            // r --> l
            for (int i = r; i >= l; i--) {
                mat[bottom][i] = num++;
            }
            bottom--;
            // bottom --> top
            for (int i = bottom; i >= top; i--) {
                mat[i][l] = num++;
            }
            l++;
        }
        return mat;
    }
}

/**
 * 方法二：按层模拟
 * 可以将矩阵看成若干层，首先填入矩阵最外层的元素，其次填入矩阵次外层的元素，直到填入矩阵最内层的元素。
 * 对于每层，从左上方开始以顺时针的顺序填入所有元素。假设当前层的左上角位于 (top, left)，
 * 右下角位于 (bottom, right)，按照如下顺序填入当前层的元素。
 *
 * 从左到右填入上侧元素，依次为 (top, left) 到 (top, right)。
 *
 * 从上到下填入右侧元素，依次为 (top + 1, right)到 (bottom, right)。
 *
 * 如果 left < right 且 top < bottom，则从右到左填入下侧元素，依次为 (bottom, right - 1) 到 (bottom, left + 1)，
 * 以及从下到上填入左侧元素，依次为 (bottom, left) 到 (top + 1, left)。
 *
 * 填完当前层的元素之后，将 left 和 top 分别增加 1，将 right 和 bottom 分别减少 1，进入下一层继续填入元素，直到填完所有元素为止。
 *
 */
